package ruleengine.worker;

import static org.awaitility.Awaitility.await;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.junit.jupiter.api.Test;

import com.ruleengine.worker.runner.rule.PubSubRuleRunner;
import com.ruleengine.worker.runner.rule.other.SimpleLogRuleRunner;

import io.vertx.core.Vertx;

/**
 * @author lianghanwei on 2024/2/19
 */
public class RuleRunnerTest {

    @Test
    public void testChainMutilSimpleRuleRunner() {
        Vertx vertx = Vertx.vertx();

        SimpleLogRuleRunner pubRuleRunner = new SimpleLogRuleRunner(vertx, "pub", null);

        List<PubSubRuleRunner> spyRuleRunnerList = IntStream.range(0, 10)
            .mapToObj(e -> {
                SimpleLogRuleRunner subRuleRunner = new SimpleLogRuleRunner(vertx, "sub-" + e, null);
                return spy(subRuleRunner);
            })
            .collect(Collectors.toList());

        pubRuleRunner.subscribe(spyRuleRunnerList.get(0));

        for (int i = 0; i < spyRuleRunnerList.size() - 1; i++) {
            PubSubRuleRunner previous = spyRuleRunnerList.get(i);
            PubSubRuleRunner next = spyRuleRunnerList.get(i + 1);

            previous.subscribe(next);
        }

        String message = "messageItem";
        pubRuleRunner.write(message);

        await().atMost(1, TimeUnit.SECONDS).until(() -> {
            for (PubSubRuleRunner runner : spyRuleRunnerList) {
                verify(runner).process(eq(message));
            }
            return true;
        });

        vertx.close();
    }
}
